window._MCFW = {

    dirArr:[[1,0],[-1,0],[0,-1],[0,1]],

    wallkey:'wall',

    //根据目标获取攻击&施法路径
    getAttackPath:function(player,targetPos,fanweimap){

        var roleData = _ROLEDATA.getRoleDataOfPlayer(player);
        var targetKey = targetPos.pos[0]+"-"+targetPos.pos[1];
        var mapobj = fanweimap[targetKey];
        var targetMovePos = null;
        var distance = roleData.distance

        //console.log('攻击目标',targetPos,targetKey,mapobj);

        if(mapobj){
            if(mapobj.attackPos){
                var attackdis = mapobj.distance;
                mapobj = mapobj.attackPos;
                //console.log('攻击目标边界点',mapobj);
                distance = roleData.distance-attackdis;
            }
            //寻找距离目标最远的攻击点
            for(var i=0;i<=distance;i++){
                if(mapobj){
                    if(!mapobj.isattack&&!mapobj.ispass){
                        targetMovePos = mapobj.pos;
                    }
                    mapobj = mapobj.prepos;   
                }
            }
        }

        if(targetMovePos){
            return _MCFW.getMovePath(player,targetMovePos[0],targetMovePos[1],fanweimap);
        }else{
            console.log('寻找攻击路径失败：',fanweimap[targetKey],roleData.distance);
        }

        return null;
    },

    //根据范围寻路
    getMovePath:function(player,tx,ty,fanweimap){


        if(
            fanweimap
            &&fanweimap[tx+"-"+ty]
            &&player
            &&player.chessPos
        ){
            var sx = player.chessPos.x;
            var sy = player.chessPos.y;
            var mapobj = fanweimap[tx+"-"+ty];
            var mappos = mapobj.pos;
            var path = [];

            while(
                mappos
                &&!(mappos[0]==sx&&mappos[1]==sy)
            ){
                path.push(mappos);
                mapobj = mapobj.prepos;
                if(mapobj){
                    mappos=mapobj.pos;
                }else{
                    mappos=null;
                }
            }

            if(path.length>0){
                path=path.reverse()
            }

            return path;
        }


        return null;

    },

    //根据地图相对坐标判断单元格是否能移动
    isMapPointCanTouchByMap:function(tiledMap,x,y,h,w,player){

        if(x>=w||y>=h||x<0||y<0){
            return false;
        }

        var titlepos = cc.v2(x,y);

        if(tiledMap.getLayer('wall')){

            if(
                tiledMap.getLayer('wall').getTileGIDAt(titlepos)!=0
            ){
                return false;
            }

        }

        return true;

    },

    //根据地图相对坐标判断单元格是否能攻击
    isMapPointCanAttackByMap:function(tiledMap,x,y,h,w){

        if(x>=w||y>=h||x<0||y<0){
            return false;
        }
        
        return true;

    },

    //如果存在嘲讽单位则优先攻击嘲讽单位
    canAttack:function(tempRole,chaofenRole){

        if(chaofenRole){

            return _CU.isSamePlayer(tempRole,chaofenRole);

        }

        return true;
    },

    //遍历寻找敌方单位
    loopFindArmy:function(param){

        var x=param.x;//当前角色坐标
        var y=param.y;
        var flag=param.flag;//当前角色阵营
        var player = param.player;//当前角色
        var chaofenRole = param.chaofenRole;//当前角色嘲讽对象

        var tiledMap = param.tiledMap;
        var maxH = param.maxH;
        var maxW = param.maxW;
        var playerNodeMap = param.playerNodeMap;

        //先确定要追击的对象
        var targetPos = null;
        if(chaofenRole){
            targetPos = chaofenRole.chessPos;
        }else{
            var minhp = -1;
            for(var key in playerNodeMap){
                var tempRole = playerNodeMap[key].info;
                if(
                    tempRole
                    &&tempRole.isplayer!=flag
                    &&!_STATUSHELPERCHESS.hasStatus(tempRole,"yin")
                ){
                    if(minhp==-1
                        ||minhp>tempRole.hp
                    ){
                        minhp = tempRole.hp;
                        targetPos = tempRole.chessPos;
                    }
                }
            }
        }

        if(!targetPos){
            return null;
        }

        //计算与目标距离
        var armydis = _CU.getPosDis(x,y,targetPos.x,targetPos.y);

        var targetPosMap = _MCFW.getPointsByDis(armydis,targetPos,{x:x,y:y});

        for(var i=0;i<armydis-1;i++){

            var targetPosArr = targetPosMap[i];

            if(targetPosArr){
                for(var j=0;j<targetPosArr.length;j++){

                    var pathPoint = _MCFW.loopFindPathPoint(player,tiledMap,maxH,maxW,targetPosArr[j]);

                    if(pathPoint){
                        return pathPoint;
                    }
                }
            }
        }
        
        return null;
        
    },

    //获取距离目标一定范围的坐标集合
    getPointsByDis:function(dis,targetPos,sourcePos){

        var result = {};

        for(var x=6;x<21;x++){
            for(var y=4;y<11;y++){
                var tempdis = _CU.getPosDis(x,y,targetPos.x,targetPos.y);
                if(tempdis<dis){
                    var sourcedis = _CU.getPosDis(x,y,sourcePos.x,sourcePos.y);
                    if(!result[tempdis]){
                        result[tempdis]=[];
                    }
                    result[tempdis].push({x:x,y:y,sdis:sourcedis});
                }
            }
        }

        for(var key in result){

            result[key].sort((a,b)=>{
                return a.sdis-b.sdis;
            });

        }
        
        return result;
    },
    
    //寻找与目标距离最短且无障碍路线的最近点
    loopFindPathPoint:function(player,tiledMap,maxH,maxW,targetPos){

        //从目标点出发寻找最近的当前角色范围点
        var dir = _MCFW.dirArr;
        var tmparr1 = [[targetPos.x,targetPos.y]];//当前遍历坐标
        var tmparr2=[];//下一轮遍历坐标
        var posSignMap = {};
        while(tmparr1.length>0){
            for(var j=0;j<tmparr1.length;j++){
                var prex = tmparr1[j][0]
                var prey = tmparr1[j][1];
                for(var k=0;k<dir.length;k++){
                    var tx = prex+dir[k][0];
                    var ty = prey+dir[k][1];
                    var tempKey = tx+"-"+ty;
                    if(
                        !posSignMap[tempKey]
                        &&_MCFW.isMapPointCanTouchByMap(tiledMap,tx,ty,maxH,maxW,player)
                    ){
                        if(
                            //!(tx==x&&ty==y)&&
                            _CHESSFIGHT.isTargetInCurrentFanweiMove(tx,ty)
                        ){
                            return {x:tx,y:ty};
                        }else{
                            posSignMap[tempKey]=1;
                            if(
                                !_CHESSFIGHT.playerNodeMap[tx+"-"+ty]
                            ){
                                tmparr2.push([tx,ty]);
                            }
                        }
                        
                    }
                }
            }
            tmparr1 = tmparr2;
            tmparr2 = [];
        }

        return null;

    },


    //判断格子是否消耗所有移动力
    //1.格子周围有敌军
    //2.格子为特殊地形且player没有对应技能
    isArmyLive:function(x,y,playerNodeMap,player,tiledMap){

        //先判断障碍地形
        var playerData = _ROLEDATA.getRoleDataOfPlayer(player);

        if(!playerData.fly){

            var titlepos = cc.v2(x,y);

            for(var key in _CHESSWALL){

                if(key!='wall'){

                    var wallConf = _CHESSWALL[key];

                    if(!playerData[wallConf.skill]){

                        if(tiledMap.getLayer(key)){
        
                            if(
                                tiledMap.getLayer(key).getTileGIDAt(titlepos)!=0
                            ){
                                return true;
                            }
        
                        }

                    }
    
            
                }
    
            }

        }

        

        


        //再判断周围是否有敌军
        var dir = _MCFW.dirArr;

        for(var k=0;k<dir.length;k++){

            var tmpkey = (x+dir[k][0])+"-"+(y+dir[k][1]);

            if(
                playerNodeMap[tmpkey]
                &&playerNodeMap[tmpkey].info.isplayer != player.isplayer
            ){
                //console.log('存在敌军',tmpkey,playerNodeMap[tmpkey],player);
                return true;
            }


        }

        return false;

    },

    getfanweiMap:function(param){

        var x= param.x;
        var y= param.y;
        var len= param.len;
        var attacklen = param.attacklen;
        var player = param.player;
        var tiledMap = param.tiledMap;
        var maxH = param.maxH;
        var maxW = param.maxW;
        var playerNodeMap = param.playerNodeMap;
        var dir = _MCFW.dirArr;
        var tmparr1 = [[x,y]],tmparr2=[];
        var result = {};
        var attackResult = {};
        result[x+"-"+y]={pos:[x,y],isattack:false};

        //先计算移动范围 排除不可进入的地形以及敌方单位 己方单位设为仅可通过
        for(var i=0;i<len;i++){
            for(var j=0;j<tmparr1.length;j++){
                for(var k=0;k<dir.length;k++){
                    var sx = tmparr1[j][0]
                    var sy = tmparr1[j][1];
                    var tx = sx+dir[k][0];
                    var ty = sy+dir[k][1];
                    var skey = sx+"-"+sy;
                    var tkey = tx+"-"+ty;
                    if(
                        !result[tkey]
                        &&_MCFW.isMapPointCanTouchByMap(tiledMap,tx,ty,maxH,maxW,player)
                    ){
                        if(!playerNodeMap[tkey]){
                            result[tkey]={pos:[tx,ty],prepos:result[skey],isattack:false};
                            if(!_MCFW.isArmyLive(tx,ty,playerNodeMap,player,tiledMap)){//判断附近是否有敌军,如果是则此点不进入下一轮循环
                                tmparr2.push([tx,ty]);
                            }
                        }else if(playerNodeMap[tkey].info.isplayer == player.isplayer){
                            result[tkey]={pos:[tx,ty],prepos:result[skey],isattack:false,ispass:true};
                            if(!_MCFW.isArmyLive(tx,ty,playerNodeMap,player,tiledMap)){//判断附近是否有敌军,如果是则此点不进入下一轮循环
                                tmparr2.push([tx,ty]);
                            }
                        }
                        
                    }
                }
            }
            tmparr1 = tmparr2;
            tmparr2 = [];
        }

        //计算移动边界 从已经计算好的路径中剔除 仅可通过以及四个方位均可进入的点
        tmparr1 = [];
        for(var key in result){

            if(!result[key].ispass){

                var isbianjie = false;
                var resultpos = result[key].pos;
                var resultx = resultpos[0];
                var resulty = resultpos[1];
                for(var k=0;k<dir.length;k++){
                    var dirkey = (resultx+dir[k][0])+"-"+(resulty+dir[k][1]);
                    if(
                        !result[dirkey]
                        ||result[dirkey].ispass
                    ){
                        isbianjie = true;
                        break;
                    }
                }

                result[key].isbianjie = isbianjie;
                tmparr1.push(resultpos);
            }

        }

        //再计算攻击范围
        for(var i=0;i<attacklen;i++){
            for(var j=0;j<tmparr1.length;j++){
                for(var k=0;k<dir.length;k++){
                    var sx = tmparr1[j][0];
                    var sy = tmparr1[j][1];
                    var tx = sx+dir[k][0];
                    var ty = sy+dir[k][1];
                    var prepos = result[sx+"-"+sy];
                    if(
                        _MCFW.isMapPointCanAttackByMap(tiledMap,tx,ty,maxH,maxW)
                    ){
                        var attackkey = tx+"-"+ty;
                        if(!result[attackkey]){
                            result[attackkey]={pos:[tx,ty],prepos:prepos,isattack:true,distance:(i+1)};
                            //回溯能攻击到此坐标的边界坐标
                            while(prepos&&!prepos.isbianjie){
                                prepos=prepos.prepos;
                            }
                            result[attackkey].attackPos = prepos;
                        }
                        if(!attackResult[attackkey]){
                            tmparr2.push([tx,ty]);
                            attackResult[attackkey]=1;
                        }
                    }
                }
            }
            tmparr1 = tmparr2;
            tmparr2 = [];
        }

        return result;
    },

    //获取道具范围
    getCurrentPlayerItemFanwei:function(itemname){
        var itemConf = _FIGHTITEM[itemname];
        var playerAqDistance = _CHESSFIGHT.currentRoleData?_CHESSFIGHT.currentRoleData.aqDistance:0;
        _CHESSFIGHT.fightSelectLabel.active = false;
        _CHESSFIGHT.currentAttackFanwei = {};
        //_MCFW.getCurrentPlayerAttackFanwei(false);
        _CHESSFIGHT.currentAttackFanwei = _MCFW.getfanweiMap(
            {
                x:_CHESSFIGHT.targetX,
                y:_CHESSFIGHT.targetY,
                len:0,
                attacklen:itemConf.distance+playerAqDistance,
                tiledMap:_CHESSFIGHT.tiledMap,
                maxH:_CHESSFIGHT.maxH,
                maxW:_CHESSFIGHT.maxW,
                playerNodeMap:_CHESSFIGHT.playerNodeMap,
                player:_CHESSFIGHT.currentPlayer
            }
        );
        _CHESSFIGHT.showfanweibyMap(_CHESSFIGHT.currentAttackFanwei);

    },


    //获取技能范围
    getCurrentPlayerSkillFanwei:function(skillName){

        var skillConf = _SKILL[skillName];
        _CHESSFIGHT.fightSelectLabel.active = false;
        _CHESSFIGHT.currentAttackFanwei = {};

        if(skillConf){

            if(skillConf.skilltype=="moveAttack"){
                

                for(var key in _CHESSFIGHT.playerNodeMap){
                    var temprole =_CHESSFIGHT.playerNodeMap[key].info;
                    if(temprole.isplayer!=_CHESSFIGHT.currentPlayer.isplayer){
                        var x = temprole.chessPos.x;
                        var y = temprole.chessPos.y;
                        _CHESSFIGHT.currentAttackFanwei[x+"-"+y]={pos:[x,y],isattack:true};
                    }
                }

            }else if(skillConf.skilltype=="moveRole"){

                for(var key in _CHESSFIGHT.playerNodeMap){
                    var temprole =_CHESSFIGHT.playerNodeMap[key].info;
                    if(
                        (
                            skillConf.target=="friend"
                            &&temprole.isplayer==_CHESSFIGHT.currentPlayer.isplayer
                            &&temprole.code!=_CHESSFIGHT.currentPlayer.code
                        )||
                        (
                            skillConf.target=="army"
                            &&temprole.isplayer!=_CHESSFIGHT.currentPlayer.isplayer
                            &&temprole.code!=_CHESSFIGHT.currentPlayer.code
                        )
                    ){
                        var x = temprole.chessPos.x;
                        var y = temprole.chessPos.y;
                        _CHESSFIGHT.currentAttackFanwei[x+"-"+y]={pos:[x,y],isattack:true};
                    }
                }

            }else if(skillConf.skilltype=="move"){

                var selfx = _CHESSFIGHT.targetX;
                var selfy = _CHESSFIGHT.targetY;
                var skilldis = _CHESSFIGHT.currentRoleData.scope+skillConf.distance;
                _CHESSFIGHT.currentAttackFanwei = _MCFW.getAllEmptyPos(true,skilldis,selfx,selfy);

            }else {

                _MCFW.getCurrentPlayerAttackFanwei(false);

            }

            _CHESSFIGHT.showfanweibyMap(_CHESSFIGHT.currentAttackFanwei);

        }

    },


    //展示攻击范围
    getCurrentPlayerAttackFanwei:function(show){

        
        _CHESSFIGHT.currentAttackFanwei = _MCFW.getfanweiMap(
                                        {
                                            x:_CHESSFIGHT.targetX,
                                            y:_CHESSFIGHT.targetY,
                                            len:0,
                                            attacklen:_CHESSFIGHT.currentRoleData.distance,
                                            tiledMap:_CHESSFIGHT.tiledMap,
                                            maxH:_CHESSFIGHT.maxH,
                                            maxW:_CHESSFIGHT.maxW,
                                            playerNodeMap:_CHESSFIGHT.playerNodeMap,
                                            player:_CHESSFIGHT.currentPlayer
                                        }
                                    );

        if(show){
            _CHESSFIGHT.fightSelectLabel.active = false;
            _CHESSFIGHT.showfanweibyMap(_CHESSFIGHT.currentAttackFanwei);
        }

    },


    //获取所有空白单元格
    getAllEmptyPos:function(isattack,distance,selfx,selfy){

        var currentAttackFanwei = {};

        for(var i=0;i<_CHESSFIGHT.maxH;i++){

            for(var j=0;j<_CHESSFIGHT.maxW;j++){

                var tempkey = j+"-"+i;
                var tempdis = _CU.getPosDis(j,i,selfx,selfy);

                if(
                    !_CHESSFIGHT.playerNodeMap[tempkey]
                    &&tempdis<distance
                    &&_MCFW.isPosInMap(j,i)
                ){

                    currentAttackFanwei[tempkey]={pos:[j,i],isattack:isattack};

                }

            }

        }

        return currentAttackFanwei;
    },


    //判断坐标是否可用 STARTX 4  STARTY 6
    isPosInMap:function(x,y){

        return x>=6
                &&y>=4
                &&x<=20
                &&y<=10;

    },


    //获取角色周围空白格子
    getPosForJump:function(player){

        var result = null;

        if(player&&player.chessPos){

            var playerPos = player.chessPos;
            var playerx = playerPos.x;
            var playery = playerPos.y;

            result = _MCFW.getPosOfTargetForJump(playerx,playery);
            
        }

        return result;
    },

    //获取目标坐标周围的四个坐标
    getPosOfTargetForJump:function(playerx,playery){

        var result = [];
            
        for(var i=0;i<_MCFW.dirArr.length;i++){

            var tx = playerx+_MCFW.dirArr[i][0];
            var ty = playery+_MCFW.dirArr[i][1];

            if(
                !_CHESSFIGHT.playerNodeMap[tx+"-"+ty]
                &&_MCFW.isPosInMap(tx,ty)
            ){
                result.push([tx,ty]);
            }
        }

        return result;

    },

    //身边是否有敌人
    isnearArmy:function(player){

        if(player&&player.chessPos){

            var playerPos = player.chessPos;
            var playerx = playerPos.x;
            var playery = playerPos.y;
            
            for(var i=0;i<_MCFW.dirArr.length;i++){

                var tx = playerx+_MCFW.dirArr[i][0];
                var ty = playery+_MCFW.dirArr[i][1];

                if(
                    _CHESSFIGHT.playerNodeMap[tx+"-"+ty]&&
                    _CHESSFIGHT.playerNodeMap[tx+"-"+ty].info.isplayer!=player.isplayer
                ){
                    return true;
                }

            }
    
        }

        return false;
    },

    getMoveTargetForJumpOut:function(){

        var jumpx = null;
        var jumpy = null;
        var minx = null;
        var miny = null;
        
        if(_CHESSFIGHT&&_CHESSFIGHT.jumpMap){
            for(var key in _CHESSFIGHT.jumpMap){
                var arr = key.split("-");
                if(arr&&arr.length==2){
                    jumpx=arr[0];
                    jumpy=arr[1];
                }
            }
        }

        if(!jumpx||!jumpy){
            return null;
        }

        var mindis = 999;
        for(var key in _CHESSFIGHT.currentFanwei){
            if(
                !_CHESSFIGHT.currentFanwei[key].isattack
                &&!_CHESSFIGHT.currentFanwei[key].ispass
            ){
                var tmpPos = _CHESSFIGHT.currentFanwei[key].pos;
                var tmpdis = _CU.getPosDis(tmpPos[0],tmpPos[1],jumpx,jumpy);
                if(tmpdis<mindis){
                    mindis = tmpdis;
                    minx = tmpPos[0];
                    miny = tmpPos[1];
                }
            }
        }

        if(minx!=null&&miny!=null){
            return {x:minx,y:miny};
        }

        return null;
    },

    //取离出口最近的地点
    getTargetForJumpOut:function(fanweiMap){

        var jumpx = null;
        var jumpy = null;
        var minx = null;
        var miny = null;
        
        if(_CHESSFIGHT&&_CHESSFIGHT.jumpMap){
            for(var key in _CHESSFIGHT.jumpMap){
                var arr = key.split("-");
                if(arr&&arr.length==2){
                    jumpx=arr[0];
                    jumpy=arr[1];
                }
            }
        }

        if(!jumpx||!jumpy){
            return null;
        }

        var mindis = 999;
        for(var key in fanweiMap){
            var tmpPos = fanweiMap[key].pos;
            var tmpdis = _CU.getPosDis(tmpPos[0],tmpPos[1],jumpx,jumpy);
            if(tmpdis<mindis){
                mindis = tmpdis;
                minx = tmpPos[0];
                miny = tmpPos[1];
            }
        }

        if(minx!=null&&miny!=null){
            return {x:minx,y:miny};
        }

        return null;
    },


    //取离所有敌方单位最远的地点
    getTargetForMoveAgain:function(fanweiMap,playerNodeMap,player){

        
        var armyPoint = [];

        for(var key in playerNodeMap){

            if(playerNodeMap[key].info.isplayer!=player.isplayer){

                armyPoint.push(playerNodeMap[key].info.chessPos);

            }

        }

        //console.log('敌方单位的点位',armyPoint);

        if(armyPoint.length<=0){
            return null;
        }

        var allPoint = [];
        for(var key in fanweiMap){

            if(!fanweiMap[key].isattack
                &&!fanweiMap[key].ispass
            ){
                var tmpPos = fanweiMap[key].pos;
                var mindis = 999;

                for(var i=0;i<armyPoint.length;i++){

                    var tmpdis = _CU.getPosDis(tmpPos[0],tmpPos[1],armyPoint[i].x,armyPoint[i].y);
                    if(tmpdis<mindis){
                        mindis = tmpdis;
                    }

                }

                allPoint.push({pos:tmpPos,mindis:mindis});
            }
        }

        if(allPoint.length<=0){
            return null;
        }else{
            allPoint.sort((a,b)=>{
                return b.mindis-a.mindis;
            });
            //console.log('可移动点位',allPoint);
            return {x:allPoint[0].pos[0],y:allPoint[0].pos[1]};
        }
    },
}